package view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.LinkedList;
import java.util.List;


/**
 * 
 * @author David Spruill and Wynne Lok
 * 
 */

public class Histogram extends Axis {
    private static final int NUM_BARS = 20;
    private int myNumBars;
    // private int myDataMin;
    // private Color myLineColor;
    private Dimension mySize;
    // private int myDataSize;
    private int myOffset;
    private int myGraphWidth;
    private int myGraphHeight;
    private Color myBarColor;

    /**
     * Sets information for bar graph.
     * 
     * @param screenSize screen size for bar graph
     * @param graphOffset graph offset for bar graph
     */
    public Histogram (Dimension screenSize, int graphOffset) {
        setSize(screenSize);
        setOffset(graphOffset);
        setGraphWidth(screenSize.width - 2 * graphOffset);
        setGraphHeight(screenSize.height - 2 * graphOffset);
    }

    @Override
    public void paint (Graphics g, List<Integer> data) {
        calculateBars(g, data);
        drawAxis(g);
    }

    /**
     * @Override
     *           public void paint (Graphics g, List<Integer> xData,
     *           List<Integer> yData) {
     *           // it doesn't make sense for a bar graph of ordered pairs
     *           paint(g, yData);
     *           }
     *           /**
     *           This sets default values for the bar graph.
     */
    public void setDefaults () {
        super.setDefaults();
        myNumBars = NUM_BARS;
        setNumberXMarkers(myNumBars);
        setNumberYMarkers(myNumBars / 2);
        setDataSize(myNumBars);
        myBarColor = Color.red;
        mySize = getMySize();
        myOffset = getOffset();
        myGraphWidth = getGraphWidth();
        myGraphHeight = getGraphHeight();
        // myDataSize = getMyDataSize();
    }

    private void calculateBars (Graphics g, List<Integer> data) {
        setDataSize(data.size());
        List<Integer> barHeight = new LinkedList<Integer>();
        int range = (int) getMyDataSize() / NUM_BARS;
        int count = 0;
        int height = 0;
        for (int x = 0; x < data.size(); x++) {

            if (count >= range || x == data.size() - 1) {
                barHeight.add(height);
                count = 0;
                height = data.get(x);
            }
            else {
                count++;
                height += data.get(x);
            }

        }
        drawBars(g, barHeight);
    }

    private void drawBars (Graphics g, List<Integer> data) {
        float barWidth = myGraphWidth / (float) myNumBars;
        // int[] bars = new int[myNumBars];

        int highestBar = 0;
        for (int currentBar : data) {
            // bars[currentBar] = countDataPointsInWidth(data, currentBar *
            // dataWidthforBar, (currentBar + 1) * dataWidthforBar);
            if (currentBar > highestBar) {
                highestBar = currentBar;
            }
        }
        setDataMax(highestBar);
        g.setColor(myBarColor);
        int barNum = 0;
        for (int currentBar : data) {
            int barHeight = (int) ((currentBar / (float) highestBar) * myGraphHeight);
            g.fillRect(myOffset + (int) barWidth * barNum, mySize.height - myOffset - barHeight,
                       (int) barWidth, barHeight);
            barNum++;
        }
    }

    /**
     * private int countDataPointsInWidth (List<Integer> data, float min, float
     * max) {
     * int count = 0;
     * for (Integer num : data) {
     * if (num <= max && num > min) {
     * count++;
     * }
     * }
     * return count;
     * }
     */
    /**
     * @param numBars the numBars to set
     */
    public void setNumBars (int numBars) {
        this.myNumBars = numBars;
    }

    /**
     * @param barColor the barColor to set
     */
    public void setBarColor (Color barColor) {
        this.myBarColor = barColor;
    }
}
